#include <stdio.h>
#include "ofc/DGraphicScreen.h"
#include "ofc/DTrueTypeFont.h"
#include "ofc/DPNGImage.h"
#include "ofc/DFile.h"

#ifdef HAVE_DGRAPHICSCREEN 
@interface MyScreen : DGraphicScreen <DScreenHandler>  // Class for the screen and its events
{
  DColor          *fgc;
  DColor          *bgc;
  DTrueTypeFont   *font;
  DGraphicSurface *image;
}
- (MyScreen *) init;
- (BOOL) open;
- (void) draw :(const char *) key;
- (BOOL) keyPress :(DKey *) key :(int) state;      // Callbacks
- (BOOL) mouseMove :(unsigned) x :(unsigned) y;
- (BOOL) mouseButtonPress :(DKey *) button :(int) state;
- (BOOL) screenResize :(unsigned) maxX :(unsigned) maxY;
- (BOOL) screenFocus :(BOOL) focus;
- (BOOL) screenRedraw :(unsigned) minX :(unsigned) maxX :(unsigned) minY :(unsigned) maxY;
@end

@implementation MyScreen

- (MyScreen *) init
{
  [super init];
  
  fgc  = [DColor new];
  bgc  = [DColor new];
  font = [DTrueTypeFont new];
  image = [DGraphicSurface new];

  return self;
}

- (BOOL) open                          // Open the screen with ..
{
  BOOL ok = NO;

  [fgc textColor :DCLR_BLACK];       // .. foreground and background color
  [bgc textColor :DCLR_WHITE];
  
  ok = [self open :600 :400 :0 :fgc :bgc];

  if (ok)
  {
    [self screenHandler :self];        // Object is handling its events itself
  }

  if (ok)
  {
    ok = [font open :"../test/arial.ttf"]; // Open the arial font

    if (ok)
    {
      [font size :"a" :15 :15];        // Size the font

      [self font :font];               // Make it the default font
    }

    if (ok)
    {
      DFile *file    = [DFile new];
      DPNGImage *png = [DPNGImage new];

      if ([file open :"ofc.png" :"rb"]) // Open the png image file
      {
        if ([png open :file])          // Give the file to the png image
        {                              // Open a graphic surface for the image
          if ([image open :[png width] :[png height] :bgc :bgc])
          {
            [image startDrawing];
            [image writeImage :0 :0 :png]; // Write the image to the surface
            [image stopDrawing];
          }
          [png close];
        }
        [file close];
       }
    }
  }
  
  return ok;
}

- (void) draw :(const char *) key      // Screen drawing
{
  int maxX = [self maxX];              // Dimensions of screen
  int maxY = [self maxY];

  char hello[] = "Hello World";
  char quit[]  = "Press q to quit";

  unsigned width,height;

  [self startDrawing];                 // Start drawing
  [self clear];
  [self drawHLine :10 :10 :maxX-10];      // Draw a some lines
  [self drawHLine :maxX-10 :maxY-10 :10];
                                       // Write some text
  [font stringSize :hello :&width :&height];

  [self cursor :((maxX - width)/2) :((maxY-40)/2)];
  [self writeText :hello];

  [font stringSize :quit :&width :&height];

  [self cursor :((maxX - width)/2) :((maxY+40)/2)];
  [self writeText :quit];

  if (key != NULL)
  {
    [self cursor :30 :maxY-30];
    [self writeText :"Key pressed:"];
    [self writeText :key];
  }
                                       // Blit the image surface on the screen
  [self blit :10 :15 :image :0 :0 :[image maxX] :[image maxY]];

  [self stopDrawing];
}
                                       // Callback for pressed key
- (BOOL) keyPress :(DKey *) key :(int) state
{
  if ([key key] != 'q')
  {
    DText *info = [key toText];
    
    [self draw :[info cstring]];

    [info free];
  }
  
  return ([key key] != 'q');
}
                                       // Callback for moved mouse
- (BOOL) mouseMove :(unsigned) x :(unsigned) y
{
  return YES;
}
                                       // Callback for pressed mouse button
- (BOOL) mouseButtonPress :(DKey *) button :(int) state
{
  return YES;
}
                                       // Callback for screen resize
- (BOOL) screenResize :(unsigned) maxX :(unsigned) maxY
{
  [self draw :NULL];

  return YES;
}
                                       // Callback for lost and gained screen focus
- (BOOL) screenFocus :(BOOL) focus
{
  [self draw :NULL];

  return YES;
}
                                       // Callback for screen redraw
- (BOOL) screenRedraw :(unsigned) minX :(unsigned) maxX :(unsigned) minY :(unsigned) maxY
{
  [self draw :NULL];

  return YES;
}

@end
#endif

int main(int argc, char *argv[])
{
#ifdef HAVE_DGRAPHICSCREEN 
  MyScreen *screen = [MyScreen new];

  if ([screen open])                   // Open the screen
  {
    [screen draw :NULL];               // Draw the screen

    [screen waitEvents];               // Wait for and process events
  }
  else
    printf("Could not open the screen..\n");

  [screen free];                       // Cleanup
#else
  printf("DGraphicScreen is not present in the library.\n");
#endif
  return 0;
}

